package org.ragdollcat.secondaiagent.app;

import org.ragdollcat.secondaiagent.advisor.MyLogAdvisor;
import org.ragdollcat.secondaiagent.advisor.SensitiveWordCheckAdvisor;
import org.ragdollcat.secondaiagent.chatmemory.DbBasedChatMemory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;

import java.util.Map;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;

@Component
public class RagdollCatApp {

    private final ChatClient chatClient;

    private static final String SYSTEM_PROMPT = "扮演深耕恋爱心理领域的专家。开场向用户表明身份，告知用户可倾诉恋爱难题。" +
            "围绕单身、恋爱、已婚三种状态提问：单身状态询问社交圈拓展及追求心仪对象的困扰；" +
            "恋爱状态询问沟通、习惯差异引发的矛盾；已婚状态询问家庭责任与亲属关系处理的问题。" +
            "引导用户详述事情经过、对方反应及自身想法，以便给出专属解决方案。";


    private final DbBasedChatMemory dbBasedChatMemory;

    private final Resource systemResource;

    public RagdollCatApp(ChatModel dashScopeChatModel,
                   DbBasedChatMemory dbBasedChatMemory,
                   @Value("classpath:/promts/system-message.st") Resource systemResource) {
        this.dbBasedChatMemory = dbBasedChatMemory;
        this.systemResource = systemResource;

        //从模板文件中读取，并且填充关键词
        SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
        String text = systemPromptTemplate.createMessage(Map.of("field", "宠物", "type", "猫咪选择")).getText();


        chatClient = ChatClient.builder(
                        dashScopeChatModel
                ).defaultSystem(text)
                //基于数据库的会话记忆保存
                .defaultAdvisors(new MessageChatMemoryAdvisor(dbBasedChatMemory),
                        //自定义日志拦截器
                        new MyLogAdvisor(),
                        //敏感词检测
                        new SensitiveWordCheckAdvisor())
                .build();

    }


    /**
     * 这里要传递一个消息ID，用于区分不同用户对话的上下文
     *
     * @param message
     * @param chatId
     * @return
     */
    public Flux<String> doChat(String message, String chatId) {
        return chatClient
                .prompt()
                .user(message)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
                .stream()
                .content();
    }

}
